﻿using DSF.Net.Controllers.Theme;
using Microsoft.Expression.Shapes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DSF.Net.Controllers.Process
{
    /// <summary>
    /// ArchProcess.xaml 的交互逻辑
    /// </summary>
    public partial class ArchProcess : UserControl,IUserTheme
    {
        public ArchProcess()
        {
            InitializeComponent();
            DataContext = this;
        }

        

        public double ZeroPoint
        {
            get { return (double)GetValue(ZeroPointProperty); }
            set { SetValue(ZeroPointProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ZeroPoint.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ZeroPointProperty =
            DependencyProperty.Register("ZeroPoint", typeof(double), typeof(ArchProcess), new PropertyMetadata(0d, (s, e) =>
            {
                var c = s as ArchProcess;
                var zero = (double)e.NewValue;
                c.ZeroLabel.Content = e.NewValue;
                c.LimitUp.Content = (double)e.NewValue + c.Limit;
                c.LimitDown.Content = (double)e.NewValue - c.Limit;
                c.BlueArcLeft.EndAngle = c.RedArcLeft.EndAngle = c.Value >= c.ZeroPoint ? 0 : -100 * (c.Value - zero) / c.Limit;
                c.BlueArcRight.EndAngle = c.RedArcRight.EndAngle = c.Value <= c.ZeroPoint ? 0 : 100 * (c.Value - zero) / c.Limit;
                c.pointerRotate.Angle = 100 * (c.Value - zero) / c.Limit;
            }));

        public double Limit
        {
            get { return (double)GetValue(LimitProperty); }
            set { SetValue(LimitProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Limit.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty LimitProperty =
            DependencyProperty.Register("Limit", typeof(double), typeof(ArchProcess), new PropertyMetadata(100d, (s, e) =>
            {
                var c = s as ArchProcess;
                var limit = (double)e.NewValue;
                c.LimitUp.Content = c.ZeroPoint + (double)e.NewValue;
                c.LimitDown.Content = c.ZeroPoint - (double)e.NewValue;
                c.BlueArcLeft.EndAngle = c.RedArcLeft.EndAngle = c.Value >= c.ZeroPoint ? 0 : -100 * (c.Value - c.ZeroPoint) / limit;
                c.BlueArcRight.EndAngle = c.RedArcRight.EndAngle = c.Value <= c.ZeroPoint ? 0 : 100 * (c.Value - c.ZeroPoint) / limit;
                c.pointerRotate.Angle = 100 * (c.Value - c.ZeroPoint) / limit;
            }));

        public double Value
        {
            get { return (double)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(double), typeof(ArchProcess), new PropertyMetadata(0d, (s, e) =>
            {
                var c = s as ArchProcess;
                var oldValue = (double)e.OldValue;
                var newValue = (double)e.NewValue;
                var animation = new DoubleAnimation
                {
                    From = oldValue,
                    To = newValue,
                    Duration = new Duration(new TimeSpan(0, 0, 0, 0, 500)),
                    EasingFunction = new QuadraticEase()
                };
                c.BeginAnimation(AnimateProperty, animation);
            }));

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Text.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TextProperty =
            DependencyProperty.Register("Text", typeof(string), typeof(ArchProcess), new PropertyMetadata("Pressure(MPa)", (s, e) =>
            {
                var c = s as ArchProcess;
                c.TitleLabel.Content = e.NewValue;
            }));

        public int Precision
        {
            get { return (int)GetValue(PrecisionProperty); }
            set { SetValue(PrecisionProperty, value); }
        }
        public Theme.Colors ThemeColor
        {
            get { return (Theme.Colors)GetValue(ThemeColorProperty); }
            set { SetValue(ThemeColorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ThemeColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ThemeColorProperty =
            DependencyProperty.Register("ThemeColor", typeof(Theme.Colors), typeof(ArchProcess), new PropertyMetadata(Theme.Colors.Default));

        // Using a DependencyProperty as the backing store for Precision.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PrecisionProperty =
            DependencyProperty.Register("Precision", typeof(int), typeof(ArchProcess), new PropertyMetadata(2, (s, e) => {
                var c = s as ArchProcess;
                var value = (int)e.NewValue;
                var priciseStr = new StringBuilder("#0.");
                for (var i = 0; i < value; i++)
                {
                    priciseStr.Append('0');
                }
                c.DataLabel.Content = c.Value.ToString(priciseStr.ToString());
            }));

        private static readonly DependencyProperty AnimateProperty =
            DependencyProperty.Register("Animate", typeof(double), typeof(ArchProcess), new PropertyMetadata(0d, (s, e) =>
            {
                var c = s as ArchProcess;
                var value = (double)e.NewValue;
                c.BlueArcLeft.EndAngle = c.RedArcLeft.EndAngle = value >= c.ZeroPoint ? 0 : -100 * (value - c.ZeroPoint) / c.Limit;
                c.BlueArcRight.EndAngle = c.RedArcRight.EndAngle = value <= c.ZeroPoint ? 0 : 100 * (value - c.ZeroPoint) / c.Limit;
                c.pointerRotate.Angle = 100 * (value - c.ZeroPoint) / c.Limit;
                var priciseStr = new StringBuilder("#0.");
                for (var i = 0; i < c.Precision; i++)
                {
                    priciseStr.Append('0');
                }
                c.DataLabel.Content = value.ToString(priciseStr.ToString());
            }));
    }
}
